/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.click.app.webapp.action;

import com.click.app.DateFormatChanger;
import com.click.app.model.Coin;
import com.click.app.model.Material;
import com.click.app.model.Purchase;
import com.click.app.model.PurchaseDetail;
import com.click.app.model.PurchasePayment;
import com.click.app.model.StorageMaterial;
import com.click.app.model.Supplier;
import com.click.app.model.User;
import com.click.app.service.GenericManager;
import com.click.app.service.PurchaseManager;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author Joel Chuca Condo
 */
public class PurchaseAction extends BaseAction {

    private PurchaseManager purchaseManager;
    private GenericManager<Supplier, Long> supplierManager;
    private GenericManager<Coin, Long> coinManager;
    private GenericManager<StorageMaterial, Long> storageMaterialManager;
    private GenericManager<Material, Long> materialManager;
    //private UserManager userManager;
    private Purchase purchase;
    private List suppliers;
    private List coins;
    private List purchases;
    private Long id;
    private boolean withDiscount;
    private boolean withBill;
    private boolean withCredit;
    private String dateMake;
    private String dateCredit;
    private Date todayDate;
    private HashMap reportParams;
    private GenericManager<PurchasePayment, Long> purchasePaymentManager;

    //DateFormatChanger changer = new DateFormatChanger();

    public void setSupplierManager(GenericManager<Supplier, Long> supplierManager) {
        this.supplierManager = supplierManager;
    }

    public void setCoinManager(GenericManager<Coin, Long> coinManager) {
        this.coinManager = coinManager;
    }

    public void setPurchaseManager(PurchaseManager purchaseManager) {
        this.purchaseManager = purchaseManager;
    }

    public void setStorageMaterialManager(GenericManager<StorageMaterial, Long> storageMaterialManager) {
        this.storageMaterialManager = storageMaterialManager;
    }

    public void setMaterialManager(GenericManager<Material, Long> materialManager) {
        this.materialManager = materialManager;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Purchase getPurchase() {
        return purchase;
    }

    public void setPurchase(Purchase purchase) {
        this.purchase = purchase;
    }

    public List getPurchases() {
        return purchases;
    }

    public void setPurchases(List purchases) {
        this.purchases = purchases;
    }

    public List getSuppliers() {
        return suppliers;
    }

    public void setSuppliers(List suppliers) {
        this.suppliers = suppliers;
    }

    public List getCoins() {
        return coins;
    }

    public void setCoins(List coins) {
        this.coins = coins;
    }

    public boolean isWithBill() {
        return withBill;
    }

    public void setWithBill(boolean withBill) {
        this.withBill = withBill;
    }

    public boolean isWithCredit() {
        return withCredit;
    }

    public void setWithCredit(boolean withCredit) {
        this.withCredit = withCredit;
    }

    public boolean isWithDiscount() {
        return withDiscount;
    }

    public void setWithDiscount(boolean withDiscount) {
        this.withDiscount = withDiscount;
    }

    public String getDateCredit() {
        dateCredit = DateFormatChanger.changeDatetoString(purchase.getTimeCredit());
        return dateCredit;
    }

    public void setDateCredit(String dateCredit) {
        this.dateCredit = dateCredit;
        getPurchase().setTimeCredit(DateFormatChanger.changeStringtoDate(dateCredit));
    }

    public String getDateMake() {
        dateMake = DateFormatChanger.changeDatetoString(purchase.getDate());
        return dateMake;
    }

    public void setDateMake(String dateMake) {
        this.dateMake = dateMake;
        purchase.setDate(DateFormatChanger.changeStringtoDate(dateMake));
    //this.dateMake = dateMake;
    }

    public Date getTodayDate() {
        return todayDate;
    }

    public void setTodayDate(Date todayDate) {
        this.todayDate = todayDate;
    }

    public String list() {
        purchases = purchaseManager.getAll();
        return SUCCESS;
    }

    public String listPaid() {
        purchases = getPaidPurchases();
        return SUCCESS;
    }
    public String listUnpaid() {
        purchases = getUnpaidPurchases();
        return SUCCESS;
    }


    public String edit() {
        System.out.println(".......... Editing ..........");

        suppliers = supplierManager.getAll();
        coins = coinManager.getAll();
        if (suppliers != null && coins != null) {
            if (id != null) {
                purchase = purchaseManager.get(id);
            } else {
                purchase = new Purchase();
                purchase.setSupplier(new Supplier());
                purchase.setCoin(new Coin());
                purchase.setDate(GregorianCalendar.getInstance().getTime());
                System.out.println(" date created " + getDateMake());
            }
            setConfigParams();
        } else {
            System.out.println(" suppliers is " + suppliers + " or coins is " + coins);
            return "error";
        }
        System.out.println("........... End Edit ..........");
        return SUCCESS;
    }

    public String save() throws Exception {
        System.out.println("PurchaseAction -> save() ");
        Double dicountOld = new Double(0);
        if (cancel != null) {
            return CANCEL;
        }        

        boolean isNew = false;
        isNew = (purchase.getId() == null);

        if (purchase.getId() != null) {
            Purchase purchaseOld = purchaseManager.get(purchase.getId());
            purchase.setTotalPrice(purchaseOld.getTotalPrice());
            purchase.setRestPrice(purchaseOld.getRestPrice());
            purchase.setDeleted(purchaseOld.getDeleted());
            purchase.setDiscountXfail(purchaseOld.getDiscountXfail());

            dicountOld = purchaseOld.getDiscount();

            if (purchaseOld.getBill() != null) {
                if (withBill) {
                    purchase.getBill().setId(purchaseOld.getBill().getId());
                    purchase.getBill().setDate(new Date());
                }
            }
        }else{
            purchase.setDeleted(true);
            purchase.setDiscountXfail(0.0D);
        }

        verifySetting();
        updatePurchaseUser();
        
        
        Double discountDifference = dicountOld - purchase.getDiscount() ;
        
        if(purchase.getRestPrice() + discountDifference >= 0){
            purchase.setRestPrice(purchase.getRestPrice()+discountDifference);

        }else{
            purchase.setDiscount(dicountOld);
        }
        purchase.setState(true);       
        purchase = purchaseManager.save(purchase);

        if(discountDifference < 0){
            PurchasePayment purchasePayment = new PurchasePayment();
            purchasePayment.setDate(purchase.getDate());
            purchasePayment.setAmount((-1)*discountDifference);
            purchasePayment.setAmountLeft(purchase.getRestPrice());
            purchasePayment.setObservation(getText("purchase.discount.observacion"));
            purchasePayment.setTypePayment(1);
            purchasePayment.setPurchase(purchase);
            purchasePaymentManager.save(purchasePayment);
        }else{
            if(discountDifference > 0){
                PurchasePayment purchasePayment = new PurchasePayment();
                purchasePayment.setDate(purchase.getDate());
                purchasePayment.setIncrementAmount(discountDifference);
                purchasePayment.setAmountLeft(purchase.getRestPrice());
                purchasePayment.setObservation(getText("purchase.incrementDiscount.observacion"));
                purchasePayment.setTypePayment(3);
                purchasePayment.setPurchase(purchase);
                purchasePaymentManager.save(purchasePayment);
            }
        }

        getSession().setAttribute("purchase", purchase);

        System.out.println("PurchaseAction -> end save() ");

        if (!isNew) {
            saveMessage(getText("purchase.updated"));
            return INPUT;
        } else {
            saveMessage(getText("purchase.added"));
            return SUCCESS;
        }
    }

    public String delete() {
        List<PurchaseDetail> purchaseDetails = purchaseManager.get(purchase.getId()).getPurchaseDetails();
        purchase.setPurchaseDetails(purchaseDetails);
        for (PurchaseDetail pd : purchaseDetails) {
            StorageMaterial storage = materialManager.get(pd.getMaterial().getId()).getStorageMaterial();
            storage.decrementStok(pd.getQuantity());
            storageMaterialManager.save(storage);
        }
        purchaseManager.remove(purchase.getId());
        saveMessage(getText("purchase.deleted"));
        return "delete";
    }

    private void setConfigParams() {
        if (purchase.getBill() != null) {
            withBill = true;
        } else {
            withBill = false;
        }

        if (purchase.getDiscount() != null) {
            withDiscount = true;
        } else {
            withDiscount = false;
        }

        if (purchase.getTimeCredit() != null) {
            withCredit = true;
        } else {
            withCredit = false;
        }
    }

    private void verifySetting() {
        //config date
        purchase.setDate(DateFormatChanger.changeStringtoDate(dateMake));

        // config discount
        if (withDiscount) {
            purchase.setDiscount(Double.parseDouble(getRequest().getParameter("purchase.discount")));
            System.out.println("With discount:");
        } else {
            purchase.setDiscount(new Double(0));
            System.out.println("Without discount:");
        }

        // config purchaseBill
        if (withBill) {
            purchase.getBill().setDate(new Date());
            System.out.println("With bill ");
        } else {
            purchase.setBill(null);
            System.out.println("Without bill:");
        }

        // config timeCredit
        if (withCredit) {
            purchase.setTimeCredit(DateFormatChanger.changeStringtoDate(dateCredit));
            System.out.println("With credit ");
        } else {
            System.out.println("Without credit:");
        }
    }

    private void updatePurchaseUser() {

        HttpServletRequest request = getRequest();

        String userName = request.getRemoteUser();
        List<User> users = userManager.getUsers(new User());
        //System.out.println(" 4 ***************************");
        for (Iterator<User> it = users.iterator(); it.hasNext();) {
            User user = it.next();
            if (user != null) {
                if (user.getUsername().equals(userName)) {
                    purchase.setUser(user);
                    System.out.println(user);
                    return;
                }
            } else {
                System.out.println("user null");
            }
        }
        System.out.println("user null");
    }

    public String help() {
        return SUCCESS;
    }

    public String helpList() {
        return SUCCESS;
    }

    public List<Purchase> getUnpaidPurchases(){
        List<Purchase> unpaidPurchases = new ArrayList<Purchase>();
        for (Purchase p: purchaseManager.getAll()){
            if (p.getRestPrice()!=0){
                unpaidPurchases.add(p);
            }
        }
        return unpaidPurchases;
    }

    public List<Purchase> getPaidPurchases(){
        List<Purchase> paidPurchases = new ArrayList<Purchase>();
        for (Purchase p: purchaseManager.getAll()){
            if (p.getRestPrice()==0){
                paidPurchases.add(p);
            }
        }
        return paidPurchases;
    }



    public String generateJasperReport() {
        System.out.println("PurchaseAction -> generateJasperReport()");
            reportParams = new HashMap();
            getReportParams().put("title", getText("purchase.heading"));
            getReportParams().put("supplier", getText("purchase.supplier.fullName"));
            getReportParams().put("total", getText("purchase.totalPrice"));
            getReportParams().put("date", getText("purchase.date"));
            System.out.println("PurchaseAction -> end generateJasperReport()");
            return SUCCESS;
    }

    public HashMap getReportParams() {
        return reportParams;
    }

    public GenericManager<PurchasePayment, Long> getPurchasePaymentManager() {
        return purchasePaymentManager;
    }

    public void setPurchasePaymentManager(GenericManager<PurchasePayment, Long> purchasePaymentManager) {
        this.purchasePaymentManager = purchasePaymentManager;
    }

}

